package com.longge.wechat.message.wxUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;










import com.longge.wechat.message.entity.AccessToken;
import com.longge.wechat.message.entity.QRCode;
import com.longge.wechat.message.entity.WxUserEntity;
import com.longge.wechat.message.entity.WebAccessToken;
import com.longge.wechat.message.menu.Menu;
import com.longge.wechat.message.post.BaseMessage;
import com.longge.wechat.utils.HttpUrl;
import com.longge.wechat.utils.ReadProperties;
import com.longge.wechat.utils.URLEncode;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;



public class WeiXinUtil {
	/**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式（GET、POST）
	 * @param outputStr 提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpRequest(String requestUrl,
			String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);

			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			System.out.println("Weixin server connection timed out.");
			ce.printStackTrace();
		} catch (Exception e) {
			System.out.println("https request error:{}");
			e.printStackTrace();
		}
		return jsonObject;
	}
	
	/*
	 * 网页授权分四步
	 * （1）获取code(网页上获取) （2）通过code换取网页授权access_token
	 * （3）刷新access_token（如果需要） （4）获取用户信息(需scope为 snsapi_userinfo)
	 */
	
	//（2）通过code换取网页授权access_token
	public final static String web_access_token_url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	
	public static WebAccessToken getWebAccessToken(String appid,String secret,String code) {
		WebAccessToken webAccessToken = null;
		String requestUrl = web_access_token_url.replace("APPID", appid).replace("SECRET", secret).replace("CODE", code);
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				webAccessToken = new WebAccessToken();
				webAccessToken.setAccess_token(jsonObject.getString("access_token"));
				webAccessToken.setExpires_in(jsonObject.getInt("expires_in"));
				webAccessToken.setRefresh_token(jsonObject.getString("refresh_token"));
				webAccessToken.setOpenId(jsonObject.getString("openid"));
				webAccessToken.setScope(jsonObject.getString("scope"));
			} catch (JSONException e) {
				webAccessToken = null;
				// 获取网页授权access_token失败
				System.out.println("获取网页授权access_token失败 errcode:{"+jsonObject.getInt("errcode")+"}errmsg:{"+ jsonObject.getString("errmsg")+"}");
			}
		}
		return webAccessToken;
	}
	
	//（3）刷新access_token（如果需要）
	public final static String refresh_token_url="https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
	
	public static WebAccessToken getRefreshAccessToken(String appid,String refresh_token) {
		WebAccessToken webAccessToken = null;
		String requestUrl = refresh_token_url.replace("APPID", appid).replace("REFRESH_TOKEN", refresh_token);
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				webAccessToken = new WebAccessToken();
				webAccessToken.setAccess_token(jsonObject.getString("access_token"));
				webAccessToken.setExpires_in(jsonObject.getInt("expires_in"));
				webAccessToken.setRefresh_token(jsonObject.getString("refresh_token"));
				webAccessToken.setOpenId(jsonObject.getString("openid"));
				webAccessToken.setScope(jsonObject.getString("scope"));
			} catch (JSONException e) {
				webAccessToken = null;
				// 刷新access_token失败
				System.out.println("刷新access_token失败 errcode:{"+jsonObject.getInt("errcode")+"}errmsg:{"+ jsonObject.getString("errmsg")+"}");
			}
		}
		return webAccessToken;
	}
	
	//（4）获取用户信息(需scope为 snsapi_userinfo)
	public final static String get_user_url="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
	
	public static WxUserEntity getUserEntity(String access_token,String openid) {
		// 调用接口获取access_token
		AccessToken accessToken = AccessToken.getInstance();
		WxUserEntity userEntity = null;
		String requestUrl = get_user_url.replace("ACCESS_TOKEN", accessToken.getToken())
				.replace("OPENID", openid);
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				userEntity = new WxUserEntity();
				userEntity.setOpenId(jsonObject.getString("openid"));
				userEntity.setNickName(jsonObject.getString("nickname"));
				userEntity.setSex(jsonObject.getString("sex"));
				userEntity.setProvince(jsonObject.getString("province"));
				userEntity.setCity(jsonObject.getString("city"));
				userEntity.setCountry(jsonObject.getString("country"));
				userEntity.setHeadimgurl(jsonObject.getString("headimgurl"));
				userEntity.setPrivilege(jsonObject.getString("privilege"));
			} catch (JSONException e) {
				userEntity = null;
				// 获取用户基本信息失败
				int errcode  = jsonObject.getInt("errcode");
				AccessToken access  = AccessToken.getInstance();
				access.error(errcode);
			}
		}
		return userEntity;
	}
	
	/*
	 * 生成带参数的二维码分2个步骤
	 * （1）创建二维码ticket 
	 * （2）通过ticket换取二维码
	 */
	
	public final static String get_ticket_url="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
	
	public final static String get_qrcode_url="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
	
	public static String creatQRCode(QRCode qrCode){
		//（1）创建二维码ticket
		AccessToken accessToken = AccessToken.getInstance();// 调用接口获取access_token
		String ticket = null;
		String requestUrl = get_ticket_url.replace("TOKEN", accessToken.getToken());
		String jsonQRCode = JSONObject.fromObject(qrCode).toString();
		System.out.println("json格式："+jsonQRCode);
		JSONObject jsonObject = httpRequest(requestUrl, "POST", jsonQRCode);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				ticket = jsonObject.getString("ticket");
			} catch (JSONException e) {
				ticket = null;
				// 获取access_token失败
				int errcode  = jsonObject.getInt("errcode");
				AccessToken access  = AccessToken.getInstance();
				access.error(errcode);
			}
		}
		
		//（2）通过ticket换取二维码,并返回二维码的地址
		return get_qrcode_url.replace("TICKET", URLEncode.escape(ticket));
	}
	
	
	//获取用户基本信息(通过关注的openId)
	public final static String get_userInfo_url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
	
	public static WxUserEntity getUserInfo(String openid) {
		// 调用接口获取access_token
		AccessToken accessToken = AccessToken.getInstance();
		WxUserEntity userEntity = null;
		String requestUrl = get_userInfo_url.replace("ACCESS_TOKEN", accessToken.getToken())
				.replace("OPENID", openid);
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				userEntity = new WxUserEntity();
				userEntity.setSubscribe(jsonObject.getString("subscribe"));
				userEntity.setOpenId(jsonObject.getString("openid"));
				userEntity.setNickName(jsonObject.getString("nickname"));
				userEntity.setSex(jsonObject.getString("sex"));
				userEntity.setLanguage(jsonObject.getString("language"));
				userEntity.setProvince(jsonObject.getString("province"));
				userEntity.setCity(jsonObject.getString("city"));
				userEntity.setCountry(jsonObject.getString("country"));
				userEntity.setHeadimgurl(jsonObject.getString("headimgurl"));
				userEntity.setSubscribe_time(jsonObject.getLong("subscribe_time"));
			} catch (JSONException e) {
				userEntity = null;
				// 获取access_token失败
				int errcode  = jsonObject.getInt("errcode");
				AccessToken access  = AccessToken.getInstance();
				access.error(errcode);
			}
		}
		return userEntity;
	}
	
	//发送客服消息
	public final static String send_info_url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
	
	public static int sendInfo(BaseMessage message) {
		// 调用接口获取access_token
		AccessToken accessToken = AccessToken.getInstance();
		int result = 0;
		String requestUrl = send_info_url.replace("ACCESS_TOKEN",accessToken.getToken());
		// 将消息对象转换成json字符串
		String jsonMessage = JSONObject.fromObject(message).toString();
		System.out.println("**************************");
		System.out.println("发送内容：\n"+jsonMessage);
		System.out.println("**************************");
		JSONObject jsonObject = httpRequest(requestUrl, "POST", jsonMessage);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				result = 1;
			} catch (JSONException e) {
				result = 0;
				// 发送客服消息失败
				// 获取用户基本信息失败
				int errcode  = jsonObject.getInt("errcode");
				AccessToken access  = AccessToken.getInstance();
				access.error(errcode);
			}
		}
		return result;
	}
	
	// 菜单创建（POST） 限100（次/天）

	public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";

	/**
	 * 创建菜单
	 * 
	 * @param menu 菜单实例
	 * @param accessToken 有效的access_token
	 * @return 0表示成功，其他值表示失败
	 */
	public static int createMenu(Menu menu) {
		int result = 0;
		// 调用接口获取access_token
		AccessToken accessToken = AccessToken.getInstance();
		// 拼装创建菜单的url
		String url = menu_create_url.replace("ACCESS_TOKEN", accessToken.getToken());
		// 将菜单对象转换成json字符串
		String jsonMenu = JSONObject.fromObject(menu).toString();
		// 调用接口创建菜单
		JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);

		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				//创建菜单失败
				result = jsonObject.getInt("errcode");
				// 获取用户基本信息失败
				int errcode  = jsonObject.getInt("errcode");
				AccessToken access  = AccessToken.getInstance();
				access.error(errcode);
			}
		}

		return result;
	}
	
	
	// 移动用户到指定分组
	public static String change_user_group = "https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token=ACCESS_TOKEN";

	/**
	 * 移动用户到指定分组
	 * 
	 * @param accessToken 有效的access_token
	 * @param outputStr 提交的数据
	 * @return 0表示成功，其他值表示失败
	 */
	public static int changeUserGroup(String outputStr) {
		// 调用接口获取access_token
		AccessToken accessToken = AccessToken.getInstance();
		int result = 0;
		// 拼装创建菜单的url
		String url = change_user_group.replace("ACCESS_TOKEN", accessToken.getToken());
		// 将菜单对象转换成json字符串
		String jsonMenu = JSONObject.fromObject(outputStr).toString();
		// 调用接口创建菜单
		JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);

		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				AccessToken access  = AccessToken.getInstance();
				access.error(result);
			}
		}

		return result;
	}
	
	
	//获取地理位置基本信息
	public final static String get_label_url="http://api.map.baidu.com/geocoder/v2/?ak=AK&callback=renderReverse&location=X,Y&output=json&pois=0";
	
	public static String getLabel(String x,String y) throws IOException {
		String ak = ReadProperties.loadProperties().getProperty("AK");
		
		String label = "";
		String requestUrl = get_label_url.replace("AK", ak).replace("X", x).replace("Y", y);
		String responseStr = HttpUrl.ConnUrl(requestUrl);
		
		responseStr = responseStr.substring(responseStr.indexOf("("));
		responseStr = "["+responseStr.substring(1,responseStr.length()-2)+"]";
		JSONArray jsonArray = JSONArray.fromObject(responseStr);
		for (int i = 0; i < jsonArray.size(); i++) {
			
			JSONObject jo = JSONObject.fromObject(jsonArray.get(i));
			JSONArray ja = JSONArray.fromObject(jo.get("result"));
			for (int j = 0; j < ja.size(); j++) {
				JSONObject jo1 = JSONObject.fromObject(ja.get(j));
				label = jo1.getString("formatted_address");
			}
			
		}
		return label;
	}
	
}
